package org.hiberlyzer.ui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.swing.JButton;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JSplitPane;
import javax.swing.JToolBar;
import javax.swing.UIManager;

import org.hiberlyzer.DataSourceFactory;

/**
 * The root UI container, which implements an MDI user interface, allowing the user to have
 * multiple QueryScreens open at the same time.
 * @author BDotzour
 *
 */
public class ApplicationWindow extends JFrame
{
	private static final String SHOW_BROWSER = "Show Browser";
	private static final String HIDE_BROWSER = "Hide Browser";
	
	private JDesktopPane desktopPane = new JDesktopPane();
	private ObjectBrowser objectBrowser;
	private JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true);
	private Set<DataSourceFactory> dataSourceFactories = new HashSet<DataSourceFactory>();
	private Map<QueryWindow, DataSourceFactory> windowFactories = new HashMap<QueryWindow, DataSourceFactory>();
	
	static
	{
	    try 
	    {
	        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
	    }
	    catch(Exception e)
	    {
	        System.out.println("Error setting native LAF: " + e);
	    }
	}
	public ApplicationWindow()
	{
		super("Hiberlyzer 0.4");
		setLayout(new BorderLayout());
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(800, 600);
		setUpMenu();
		setUpToolbar();
		desktopPane.setBackground(Color.GRAY);
		add(desktopPane, BorderLayout.CENTER);
	}
	
	public ApplicationWindow(DataSourceFactory dataSourceFactory)
	{
		this();
		dataSourceFactories.add(dataSourceFactory);
		objectBrowser = new ObjectBrowser(dataSourceFactory.acquireDataSource());
		objectBrowser.setVisible(false);
		openNewQueryWindow(dataSourceFactory);
	}

	private void setUpMenu()
	{
		JMenuBar menuBar = new JMenuBar();
		JMenu fileMenu = new JMenu("File");
		
		JMenuItem newWindowItem = new JMenuItem("New window", KeyEvent.VK_N);
		newWindowItem.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e)
			{
				QueryWindow activeWindow = (QueryWindow) desktopPane.getSelectedFrame();
				if(activeWindow != null)
				{
					DataSourceFactory factoryForWindow = windowFactories.get(activeWindow);
					openNewQueryWindow(factoryForWindow);
				}
			}});
		fileMenu.add(newWindowItem);
				
		fileMenu.addSeparator();
		JMenuItem exitMenuItem = new JMenuItem("Exit", KeyEvent.VK_X);
		exitMenuItem.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e)
			{
				System.exit(0);
			}});
		fileMenu.add(exitMenuItem);
		menuBar.add(fileMenu);
		setJMenuBar(menuBar);
	}
	
	private void setUpToolbar()
	{
		JToolBar toolBar = new JToolBar();
		final JButton objectBrowserButton = new JButton(SHOW_BROWSER);
		objectBrowserButton.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e)
			{
				if(objectBrowser.isVisible())
				{
					hideObjectBrowser();
					objectBrowserButton.setText(SHOW_BROWSER);
				}
				else
				{
					displayObjectBrowser();
					objectBrowserButton.setText(HIDE_BROWSER);
				}
			}});
		toolBar.add(objectBrowserButton);
		
		add(toolBar, BorderLayout.NORTH);
	}
	
	private void openNewQueryWindow(DataSourceFactory dataSourceFactory)
	{
		QueryWindow queryWindow = new QueryWindow(dataSourceFactory.acquireDataSource());
		desktopPane.add(queryWindow);
		windowFactories.put(queryWindow, dataSourceFactory);
		JInternalFrame activeFrame = desktopPane.getSelectedFrame();
		if(activeFrame != null)
		{
			queryWindow.setLocation(new Point(activeFrame.getLocation().x + 10, activeFrame.getLocation().y + 10));
		}
		queryWindow.setVisible(true);
		desktopPane.setSelectedFrame(queryWindow);
	}
	
	private void displayObjectBrowser()
	{
		remove(desktopPane);
		objectBrowser.setVisible(true);
		splitPane.add(objectBrowser, JSplitPane.LEFT);
		splitPane.add(desktopPane, JSplitPane.RIGHT);
		splitPane.setDividerLocation(200);
		splitPane.setDividerSize(5);
		add(splitPane, BorderLayout.CENTER);
	}
	
	private void hideObjectBrowser()
	{
		objectBrowser.setVisible(false);
		splitPane.remove(objectBrowser);
		splitPane.remove(desktopPane);
		remove(splitPane);
		add(desktopPane, BorderLayout.CENTER);
	}
}
